import java.util.ArrayList;
import java.util.List;

public class PrimosParaleloSemRegiaoCritica extends Thread {
	private List<Integer> listaDePrimos;
	private int inicio;
	private int fim;

	private PrimosParaleloSemRegiaoCritica(int inicio, int fim) {
		this.inicio = inicio;
		this.fim = fim;
	}

	public void run() {
//		long antes = System.nanoTime();
		listaDePrimos = PrimosSequencial.buscaPrimos(inicio, fim);
//		long depois = System.nanoTime();
//		long tempoEmNs = depois - antes;
//		System.out.println("Thread do intervalo [" + inicio + "," + fim
//				+ "] acabou em " + tempoEmNs + " nanossegundos ("
//				+ (tempoEmNs / 1000000F) + " milissegundos) e achou "
//				+ listaDePrimos.size() + " primos!");
	}

	public static List<Integer> buscaPrimos(int intervaloInicio,
			int intervaloFim, int numThreads) throws InterruptedException {
		List<PrimosParaleloSemRegiaoCritica> threads = inicializaThreads(
				intervaloInicio, intervaloFim, numThreads);

		for (Thread thread : threads) {
			thread.start();
		}
		for (Thread thread : threads) {
			thread.join();
		}

		List<Integer> combinacao = new ArrayList<Integer>();
		for (PrimosParaleloSemRegiaoCritica primos : threads) {
			combinacao.addAll(primos.listaDePrimos);
		}
		return combinacao;
	}

	private static List<PrimosParaleloSemRegiaoCritica> inicializaThreads(
			int inicio, int fim, int numThreads) {
		int blocos = ((fim - inicio) + 1) / numThreads;

		int inicioAux = inicio;
		int fimAux = inicioAux + blocos;

		List<PrimosParaleloSemRegiaoCritica> listaThreads = new ArrayList<PrimosParaleloSemRegiaoCritica>();
		for (int i = 0; i < numThreads; i++) {
			if ((fimAux) > fim) {
				fimAux = fim;
			}

			PrimosParaleloSemRegiaoCritica pi = new PrimosParaleloSemRegiaoCritica(
					inicioAux, fimAux);
			listaThreads.add(pi);
			
			inicioAux = (fimAux + 1);
			fimAux = inicioAux + blocos;
		}

		return listaThreads;
	}
}
